# used libraries
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("plotly")) install.packages("plotly")
# R package DT provides an R interface to the JavaScript library DataTables.
if (!require("DT")) install.packages("DT")
# geom_mark_hull
if (!require("concaveman")) install.packages("concaveman")
if (!require("ggforce")) install.packages("ggforce")
# more libraries
if (!require("listviewer")) install.packages("listviewer")
if (!require("lubridate")) install.packages("lubridate")
if (!require("forcats")) install.packages("forcats")
if (!require("maps")) install.packages("maps")
if (!require("mvtnorm")) install.packages("mvtnorm")
if (!require("gapminder")) install.packages("gapminder")
if (!require("hexbin")) install.packages("hexbin")
if (!require("Hmisc")) install.packages("Hmisc")
This document is essentially a brief notes of the book above.
library(plotly)
fig1 <- list(
data = list(
list(
x = c(1, 2, 3),
y = c(1, 3, 2),
type = 'bar'
)
),
layout = list(
title = 'A Figure Specified By R List',
plot_bgcolor='#e5ecf6',
xaxis = list(
zerolinecolor = '#ffff',
zerolinewidth = 2,
gridcolor = 'ffff'),
yaxis = list(
zerolinecolor = '#ffff',
zerolinewidth = 2,
gridcolor = 'ffff')
)
)
# To display the figure defined by this list, use the plotly_build function
plotly_build(fig1)
library(plotly)
fig2 <- plot_ly(x = c(1, 2, 3), y = c(1, 3, 2), type = 'bar')%>%
layout(title = 'A Plotly Figure',
plot_bgcolor='#e5ecf6',
xaxis = list(
zerolinecolor = '#ffff',
zerolinewidth = 2,
gridcolor = 'ffff'),
yaxis = list(
zerolinecolor = '#ffff',
zerolinewidth = 2,
gridcolor = 'ffff'))
fig2
str(fig2, max.level = 2)
## List of 8
## $ x :List of 7
## ..$ visdat :List of 1
## ..$ cur_data : chr "18e8757d1eb5"
## ..$ attrs :List of 1
## ..$ layout :List of 3
## ..$ source : chr "A"
## ..$ config :List of 2
## ..$ layoutAttrs:List of 1
## ..- attr(*, "TOJSON_FUNC")=function (x, ...)
## $ width : NULL
## $ height : NULL
## $ sizingPolicy :List of 6
## ..$ defaultWidth : chr "100%"
## ..$ defaultHeight: num 400
## ..$ padding : num 0
## ..$ viewer :List of 6
## ..$ browser :List of 5
## ..$ knitr :List of 3
## $ dependencies :List of 5
## ..$ :List of 10
## .. ..- attr(*, "class")= chr "html_dependency"
## ..$ :List of 10
## .. ..- attr(*, "class")= chr "html_dependency"
## ..$ :List of 10
## .. ..- attr(*, "class")= chr "html_dependency"
## ..$ :List of 10
## .. ..- attr(*, "class")= chr "html_dependency"
## ..$ :List of 10
## .. ..- attr(*, "class")= chr "html_dependency"
## $ elementId : NULL
## $ preRenderHook:function (p, registerFrames = TRUE)
## $ jsHooks : list()
## - attr(*, "class")= chr [1:2] "plotly" "htmlwidget"
## - attr(*, "package")= chr "plotly"
plotly_json(fig2)
## {
## "visdat": {
## "18e8757d1eb5": ["function () ", "plotlyVisDat"]
## },
## "cur_data": "18e8757d1eb5",
## "attrs": {
## "18e8757d1eb5": {
## "x": [1, 2, 3],
## "y": [1, 3, 2],
## "alpha_stroke": 1,
## "sizes": [10, 100],
## "spans": [1, 20],
## "type": "bar"
## }
## },
## "layout": {
## "margin": {
## "b": 40,
## "l": 60,
## "t": 25,
## "r": 10
## },
## "title": "A Plotly Figure",
## "plot_bgcolor": "#e5ecf6",
## "xaxis": {
## "domain": [0, 1],
## "automargin": true,
## "zerolinecolor": "#ffff",
## "zerolinewidth": 2,
## "gridcolor": "ffff",
## "title": []
## },
## "yaxis": {
## "domain": [0, 1],
## "automargin": true,
## "zerolinecolor": "#ffff",
## "zerolinewidth": 2,
## "gridcolor": "ffff",
## "title": []
## },
## "hovermode": "closest",
## "showlegend": false
## },
## "source": "A",
## "config": {
## "modeBarButtonsToAdd": ["hoverclosest", "hovercompare"],
## "showSendToCloud": false
## },
## "data": [
## {
## "x": [1, 2, 3],
## "y": [1, 3, 2],
## "type": "bar",
## "marker": {
## "color": "rgba(31,119,180,1)",
## "line": {
## "color": "rgba(31,119,180,1)"
## }
## },
## "error_y": {
## "color": "rgba(31,119,180,1)"
## },
## "error_x": {
## "color": "rgba(31,119,180,1)"
## },
## "xaxis": "x",
## "yaxis": "y",
## "frame": null
## }
## ],
## "highlight": {
## "on": "plotly_click",
## "persistent": false,
## "dynamic": false,
## "selectize": false,
## "opacityDim": 0.2,
## "selected": {
## "opacity": 1
## },
## "debounce": 0
## },
## "shinyEvents": ["plotly_hover", "plotly_click", "plotly_selected", "plotly_relayout", "plotly_brushed", "plotly_brushing", "plotly_clickannotation", "plotly_doubleclick", "plotly_deselect", "plotly_afterplot", "plotly_sunburstclick"],
## "base_url": "https://plot.ly"
## }
plotly.R to plotly.js
The Figure Data Structure (plotly object attributes):
Creating plotly object
plot_ly()/plot_geo()/plot_mapbox()ggplotly())plotly_build())plot_ly(): * ‘direct’ interface to plotly.js * additional abstractions to help reduce typing * Similar to ggplot2 plotly also implement Grammar of Graphics
# load the plotly R package
library(plotly)
# load the diamonds dataset from the ggplot2 package
data(diamonds, package = "ggplot2")
#knitr::kable(diamonds)
diamonds
# create three visualizations of the diamonds dataset
plot_ly(diamonds, x = ~cut)
## No trace type specified:
## Based on info supplied, a 'histogram' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#histogram
plot_ly(diamonds, x = ~cut, y = ~clarity)
## No trace type specified:
## Based on info supplied, a 'histogram2d' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#histogram2d
# using Accent palettes from RColorBrewer try Set1, Paired and others
plot_ly(diamonds, x = ~cut, color = ~clarity, colors = "Accent", type="histogram")
# doesn't produce black bars, 'black' is value here
plot_ly(diamonds, x = ~cut, color = "black")
## No trace type specified:
## Based on info supplied, a 'histogram' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#histogram
# produces red bars with black outline
plot_ly(
diamonds,
x = ~cut,
color = I("red"),
stroke = I("black"),
span = I(2)
)
## No trace type specified:
## Based on info supplied, a 'histogram' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#histogram
Use
I(<value>)to specify color, mark and similar
Most function from plotly takes a plotly object as first argument and thus can participate in %>% chaining.
layout(
plot_ly(diamonds, x = ~cut),
title = "My beatiful histogram"
)
## No trace type specified:
## Based on info supplied, a 'histogram' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#histogram
%>% often produce more human readable code
diamonds %>%
plot_ly(x = ~cut) %>%
layout(title = "My beatiful histogram")
## No trace type specified:
## Based on info supplied, a 'histogram' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#histogram
diamonds %>%
plot_ly() %>%
add_histogram(x = ~cut)
diamonds %>%
dplyr::count(cut) %>%
plot_ly() %>%
add_bars(x = ~cut, y = ~n)
What is the difference between two above plots?
Calculations done in different places (it can be important for speed and interactivity).
add_() functions: add_histogram2d(), add_contour(), add_boxplot()
plot_ly(): * Arguments specified in plot_ly() are global, meaning that any downstream add_() functions inherit these arguments (unless inherit = FALSE). manipulation verbs from the dplyr package may be used to transform the data underlying a plotly object. * use the plotly_data() to get data
library(dplyr)
diamonds %>%
plot_ly(x = ~cut) %>%
add_histogram() %>%
group_by(cut) %>%
summarise(n = n()) %>%
add_text(
text = ~scales::comma(n), y = ~n,
textposition = "top middle",
cliponaxis = FALSE
)
p <- ggplot(diamonds, aes(x = log(carat), y = log(price))) +
geom_hex(bins = 100)
ggplotly(p)
p <- ggplot(diamonds, aes(x = log(price), color = clarity)) +
geom_freqpoly()
ggplotly(p)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
p <- ggplot(diamonds, aes(x = log(price), color = clarity)) +
geom_freqpoly(stat = "density") +
facet_wrap(~cut)
ggplotly(p)
m <- lm(log(price) ~ log(carat), data = diamonds)
diamonds <- modelr::add_residuals(diamonds, m)
p <- ggplot(diamonds, aes(x = clarity, y = resid, color = clarity)) +
ggforce::geom_sina(alpha = 0.1) +
stat_summary(fun.data = "mean_cl_boot", color = "black") +
facet_wrap(~cut)
# WebGL is a lot more efficient at rendering lots of points
toWebGL(ggplotly(p))
Some scatter type add_* routines: * add_markers() * add_lines() * add_paths() * add_segments() * add_ribbons() * add_area() * add_polygons()
library(plotly)
data(economics, package = "ggplot2")
economics
# show difference between paths and lines
p <- economics[sample(nrow(economics)),] %>%
plot_ly(x = ~date, y = ~psavert)
add_paths(p)
add_lines(p)
add_lines(p) %>% rangeslider()
library(lubridate)
econ <- economics %>%
mutate(yr = year(date), mnth = month(date))
# One trace (more performant, but less interactive) NOTE: group_by use
econ %>%
group_by(yr) %>%
plot_ly(x = ~mnth, y = ~uempmed) %>%
add_lines()
# Multiple traces (less performant, but more interactive)
plot_ly(econ, x = ~mnth, y = ~uempmed) %>%
add_lines(color = ~ordered(yr))
# The split argument guarantees one trace per group level (regardless
# of the variable type). This is useful if you want a consistent
# visual property over multiple traces
plot_ly(econ, x = ~mnth, y = ~uempmed) %>%
add_lines(split = ~yr, color = I("black"))
#three above methods vary in interactivity and scaling/performance
# more raw plotly.js style, only add_trace
set.seed(99)
plot_ly() %>%
add_trace(
type = "scatter",
mode = "markers+lines+text",
x = 4:6,
y = 4:6,
text = replicate(3, "Here is the text 🙌"),
textposition = "right",
hoverinfo = "text",
textfont = list(family = "Roboto Condensed", size = 16)
) %>%
layout(xaxis = list(range = c(3, 8)))
schema()
# add_markers adds markers/points
# alpha color can help with overcrowding
# too many points can be compute intensive, try toWebGL
# eventually you will need to use 2d histogram
subplot(
plot_ly(mpg, x = ~cty, y = ~hwy, name = "default"),
plot_ly(mpg, x = ~cty, y = ~hwy) %>%
add_markers(alpha = 0.2, name = "alpha")
)
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
## No scatter mode specifed:
## Setting the mode to markers
## Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
use suplot() for placing multiple plots on same figure
# use help and make it share X and Y axes
subplot(
plot_ly(mpg, x = ~cty, y = ~hwy, name = "default"),
plot_ly(mpg, x = ~cty, y = ~hwy) %>%
add_markers(alpha = 0.2, name = "alpha"),
shareX=TRUE, shareY=T
)
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
## No scatter mode specifed:
## Setting the mode to markers
## Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
Discrete vs continuous color scale.
# discrete variable to color produces one trace per category,
# numeric variable to color produces one trace
# colorbar() - ustomize the appearance of scale bar
p <- plot_ly(mpg, x = ~cty, y = ~hwy, alpha = 0.5)
subplot(
add_markers(p, color = ~cyl, showlegend = FALSE) %>%
colorbar(title = "Viridis"),
add_markers(p, color = ~factor(cyl))
)
Palettes types: * Sequential * gradual change from one color to another * typically light color to dark color * Good for continuous data, differentiate min and max * Diverging * Often gradual change between three colors * Good for continuous data, differentiate min, medium and max) * Qualitative * discrete color change, distinct colors between different values * Good for categories
library(RColorBrewer)
par(mar=c(3,4,2,2))
display.brewer.all()
subplot(
add_markers(p, color = ~cyl, colors = c("red", "#000000", "blue")) %>%
colorbar(title = "plotly"),
add_markers(p, color = ~cyl, colors = "Spectral") %>% # RColorBrewer::brewer.pal.info for more
colorbar(title = "RColorBrewer::Spectral"),
add_markers(p, color = ~cyl, colors = viridisLite::inferno(10)) %>%
colorbar(title = "viridisLite::Inferno"),
add_markers(p, color = ~cyl, colors = colorRamp(c("red", "white", "blue"))) %>%
colorbar(title = "colorRamp"),
nrows = 2
) %>% hide_legend()
subplot(
# plotly
add_markers(p, color = ~factor(cyl), colors = c("red", "#000000", "blue","green"),
legendgroup = '1'),
# plotly by values
add_markers(p, color = ~factor(cyl), colors = c('4'="red", '5'="black", '6'="blue", '8'="green"),
legendgroup = '2'),
# RColorBrewer::Set1
add_markers(p, color = ~factor(cyl), colors = "Set1",
legendgroup = '3'),
# colorRamp or other continious maps
add_markers(p, color = ~factor(cyl), colors = colorRamp(c("red", "white", "blue")),
legendgroup = '4'),
nrows = 2
)
# one legend per whole plot at this time, legendgroup allows grouping and some padding
subplot(
add_markers(p, color = ~cyl, colors = c("red", "#000000", "blue")) %>%
colorbar(title = "plotly"),
add_markers(p, color = ~cyl, colors = "Spectral") %>% # RColorBrewer::brewer.pal.info for more
colorbar(title = "RColorBrewer::Spectral"),
add_markers(p, color = ~cyl, colors = viridisLite::inferno(10)) %>%
colorbar(title = "viridisLite::Inferno"),
add_markers(p, color = ~cyl, colors = colorRamp(c("red", "white", "blue"))) %>%
colorbar(title = "colorRamp"),
nrows = 2
) %>% hide_legend()
Symbols
p <- plot_ly(mpg, x = ~cty, y = ~hwy, alpha = 0.3)
subplot(
add_markers(p, symbol = ~cyl, name = "A single trace"),
add_markers(p, symbol = ~factor(cyl), color = I("black")),
add_markers(
p, color = I("black"),
symbol = ~factor(cyl),
symbols = c("triangle-up", "diamond", "circle")
),
add_markers(p, size = ~cyl, sizes = c(1, 500), name = "custom"),
nrows = 2
)
# stroke, span, size also can be changed
# add_segments
mpg %>%
group_by(model) %>%
summarise(c = mean(cty), h = mean(hwy)) %>%
mutate(model = forcats::fct_reorder(model, c)) %>% # forcats::fct_reorder for factor reorder
plot_ly() %>%
add_segments(
x = ~c, y = ~model,
xend = ~h, yend = ~model,
color = I("gray"), showlegend = FALSE
) %>%
add_markers(
x = ~c, y = ~model,
color = I("blue"),
name = "mpg city"
) %>%
add_markers(
x = ~h, y = ~model,
color = I("red"),
name = "mpg highway"
) %>%
layout(xaxis = list(title = "Miles per gallon"))
# leveraging density function to plot kernel dencity estimation
kerns <- c("gaussian", "epanechnikov", "rectangular",
"triangular", "biweight", "cosine", "optcosine")
p <- plot_ly()
for (k in kerns) {
d <- density(economics$pce, kernel = k, na.rm = TRUE)
p <- add_lines(p, x = d$x, y = d$y, name = k)
}
p
# or
ggplotly(ggplot(economics, aes(x=pce))+geom_density())